import { z } from "zod/v4";
import {
  PromptChatMessageListSchema,
  PromptNameSchema,
  COMMIT_MESSAGE_MAX_LENGTH,
  PromptType,
} from "@langfuse/shared";

const createNewPromptBaseSchema = (
  t: (key: string, params?: Record<string, unknown>) => string,
) =>
  z.object({
    // Localize the required name, and keep other PromptNameSchema rules
    name: z
      .string()
      .min(1, t("pages.prompts.new.errors.enterName"))
      .and(PromptNameSchema),
    isActive: z.boolean({
      error: "Enter whether the prompt should go live",
    }),
    config: z.string().refine(validateJson, "Config needs to be valid JSON"),
    commitMessage: z
      .string()
      .trim()
      .min(1)
      .max(COMMIT_MESSAGE_MAX_LENGTH)
      .optional(),
  });

const createNewChatPromptSchema = (
  t: (key: string, params?: Record<string, unknown>) => string,
) =>
  createNewPromptBaseSchema(t).extend({
    type: z.literal(PromptType.Chat),
    chatPrompt: PromptChatMessageListSchema.refine(
      (messages) => messages.every((message) => message.content.length > 0),
      t("pages.prompts.new.errors.enterChatMessageOrRemove"),
    ),
    textPrompt: z.string(),
  });

const createNewTextPromptSchema = (
  t: (key: string, params?: Record<string, unknown>) => string,
) =>
  createNewPromptBaseSchema(t).extend({
    type: z.literal(PromptType.Text),
    chatPrompt: z.array(z.any()),
    // Localize "Enter a prompt"
    textPrompt: z.string().min(1, t("pages.prompts.new.errors.enterPrompt")),
  });

export const createNewPromptFormSchema = (
  t: (key: string, params?: Record<string, unknown>) => string,
) =>
  z.discriminatedUnion("type", [
    createNewChatPromptSchema(t),
    createNewTextPromptSchema(t),
  ]);
export type NewPromptFormSchemaType = z.infer<
  ReturnType<typeof createNewPromptFormSchema>
>;

export const PromptVariantSchema = z.union([
  z.object({
    type: z.literal(PromptType.Chat),
    prompt: PromptChatMessageListSchema,
  }),
  z.object({
    type: z.literal(PromptType.Text),
    prompt: z.string(),
  }),
]);
export type PromptVariant = z.infer<typeof PromptVariantSchema>;

function validateJson(content: string): boolean {
  try {
    JSON.parse(content);

    return true;
  } catch (e) {
    return false;
  }
}
